package com.qf.microuser.user.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qf.common.core.entity.User;
import com.qf.common.core.exception.CommonException;
import com.qf.common.core.utils.JwtUtils;
import com.qf.common.core.utils.UserUtils;
import com.qf.common.sms.utils.AliSmsUtils;
import com.qf.microuser.user.mapper.UserMapper;
import com.qf.microuser.user.param.LoginParam;
import com.qf.microuser.user.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.Map;

/**
 * --- 缘分让我们相遇乱世以外 ---
 *
 * @author SJY
 * 2024/12/26
 * 业务层调用本模块dao层,调用其他模块业务层
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public String login(LoginParam loginParam) {
        // 判断用户名密码是否正确
        User user = userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getUsername, loginParam.getUsername()));
        if (user == null) {
            throw new CommonException("用户名或密码错误");
        }
        // 针对前端传来的密码进行md5加密
        String md5Pwd = SecureUtil.md5(loginParam.getPassword());

        if (!user.getPassword().equals(md5Pwd)) {
            throw new CommonException("用户名或密码错误");
        }

        // // 生成token,方案一:
        // String token = UUID.randomUUID().toString().replaceAll("-", "");
        // // String key = "token:" + token;
        // // "token:%s"
        // String key = String.format(RedisKeyEnum.KEY_LOGIN.getKey(), token);
        // redisUtil.setCacheObject(key, user, RedisKeyEnum.KEY_LOGIN.getTime(), TimeUnit.SECONDS);

        // 方案二: jwt做token验证...
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getId());
        String token = JwtUtils.createJwt(map);
        return token;
    }

    @Override
    public User my() {
        // Integer uid = TokenUtils.getUid();
        //从ThreadLocal中获取用户id
        Integer uid = UserUtils.getUid();
        return userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getId, uid));
    }

    @Override
    public String sendCode(String phone) {

        String code = "3434";
        // 异步发送短信(线程池\mq)
        // 如果异步发送失败如何处理?
        // 方案1: 发送异常,只是记录异常日志,但是代码上不做处理,达到指定时间后,客户端可以再次点击按钮发送
        // 方案2: 发送异常,进行补偿机制(直接内部捕获异常,再次调用发送操作)
        // threadPoolExecutor.execute(() -> {
        //     AliSmsUtils.sendSms(
        //             "阿里云短信测试",
        //             "SMS_154950909",
        //             phone,
        //             code
        //     );
        AliSmsUtils.sendSms(
                "阿里云短信测试",
                "SMS_154950909",
                phone,
                code
        );
        // 存入redis
        //redisUtil.setCacheObject(phone, code, 10*600, TimeUnit.SECONDS);
        // 存入redis成功后,返回成功信息
        return code;
    }

    @Override
    public void addLogin(User user) {
        // 对用户密码进行MD5加密
        String originalPassword = user.getPassword();
        //String md5Pwd = SecureUtil.md5(originalPassword);

        // 将加密后的密码设置回User对象
        user.setPassword(originalPassword);

        // 插入用户信息到数据库
        int i = userMapper.insert(user);
        if (i != 1) {
            throw new CommonException("添加用户失败");
        }
    }

    @Override
    public void updatePoint(Integer uid, Integer point) {
        userMapper.updatePoint(uid, point);
    }
}
